package org.chen.service.impl;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.chen.config.SnowflakeIdGenerator;
import org.chen.dto.MovieDTO;
import org.chen.enu.ContentPosition;
import org.chen.exception.ServiceException;
import org.chen.template.MovieDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Component
@Slf4j
public class MovieJsonGenerator {
    private final ObjectMapper objectMapper;

    @Autowired
    private MovieTemplateService templateService;

    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;

    public MovieJsonGenerator() {
        this.objectMapper = new ObjectMapper();
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
        objectMapper.setTimeZone(TimeZone.getTimeZone("UTC"));
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    // 生成多个模板的JSON
    public String generateRandomJson(MovieDTO movieDTO) {
        validateInput(movieDTO);

        // 获取所有模板
        List<MovieDetail> templates = templateService.getAllEnabledTemplates();

        // 随机选择一个模板
        int randomIndex = new Random().nextInt(templates.size());
        MovieDetail selectedTemplate = templates.get(randomIndex);

        // 如果是随机位置，先确定位置
        ContentPosition finalPosition = movieDTO.getContentPosition();
        if (finalPosition == ContentPosition.RANDOM) {
            finalPosition = getRandomPosition();
        }

        try {
            return generateSingleJson(movieDTO, selectedTemplate, finalPosition);
        } catch (Exception e) {
            log.error("生成模板JSON失败: {}", selectedTemplate, e);
            throw new ServiceException("生成JSON失败");
        }
    }

    // 生成 slug
    private String generateSlug(String slug) {
        return slug.toLowerCase()
                .replaceAll("[^\\p{L}\\p{N}\\s-]", "")
                .replaceAll("\\s+", "-");
    }

    // 生成单个模板的JSON
    private String generateSingleJson(MovieDTO movieDTO, MovieDetail template, ContentPosition position) {
        try {
            // 深拷贝模板
            MovieDetail newMovie = objectMapper.readValue(
                    objectMapper.writeValueAsString(template),
                    MovieDetail.class
            );

            long id = snowflakeIdGenerator.nextId();
            // 更新基本信息
            newMovie.getMovie().setName(movieDTO.getName());
            newMovie.getMovie().setSlug(generateSlug(movieDTO.getSlug()));
            newMovie.getMovie().getTmdb().setId(String.valueOf(id));
            newMovie.getMovie().set_id(String.valueOf(id));

            // 处理content
            String content;
            if (movieDTO.getContent() != null) {
                // 如果用户提供了content，使用用户的content
                content = processContent(
                        movieDTO.getName(),
                        movieDTO.getContent(),
                        movieDTO.getContentPosition()
                );
            } else {
                // 否则使用模板的content
                content = processContent(
                        movieDTO.getName(),
                        template.getMovie().getContent(),
                        movieDTO.getContentPosition()
                );
            }
            newMovie.getMovie().setContent(content);

            // 更新时间戳
            String currentTime = DateTimeFormatter
                    .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
                    .format(LocalDateTime.now(ZoneOffset.UTC));
            newMovie.getMovie().getCreated().setTime(currentTime);
            newMovie.getMovie().getModified().setTime(currentTime);

            return objectMapper.writeValueAsString(newMovie);
        } catch (Exception e) {
            throw new ServiceException("生成JSON失败: " + e.getMessage());
        }
    }

    private ContentPosition getRandomPosition() {
        ContentPosition[] positions = {
                ContentPosition.START,
                ContentPosition.END,
                ContentPosition.MIDDLE,
        };
        return positions[new Random().nextInt(positions.length)];
    }

    private void validateInput(MovieDTO movieDTO) {
        if (movieDTO == null) {
            throw new ServiceException("输入数据不能为空");
        }
        if (StringUtils.isEmpty(movieDTO.getName())) {
            throw new ServiceException("名称不能为空");
        }
        if (movieDTO.getContentPosition() == null) {
            throw new ServiceException("内容位置不能为空");
        }
    }

    // processContent 方法保持不变
    private String processContent(String name, String content, ContentPosition position) {
        String nameTag = name;

        switch (position) {
            case START:
                nameTag = name + "-";
                // 检查是否有<p>标签
                if (content.startsWith("<p>")) {
                    // 插入nameTag在第一个<p>后
                    int startTagEnd = content.indexOf(">") + 1;
                    return content.substring(0, startTagEnd) +
                            nameTag +
                            content.substring(startTagEnd);
                } else {
                    // 无<p>标签，直接加到开头
                    return nameTag + content;
                }
            case END:
                // 检查是否有<p>标签
                if (content.endsWith("</p>")) {
                    // 插入nameTag在最后一个</p>前
                    int lastTagStart = content.lastIndexOf("</p>");
                    return content.substring(0, lastTagStart) +
                            nameTag +
                            content.substring(lastTagStart);
                } else {
                    // 无<p>标签，直接加到结尾
                    return content + nameTag;
                }
            case MIDDLE:
                // 找到内容的中间位置
                int midPoint = content.length() / 2;
                // 找到中间位置最近的完整单词边界
                int insertPoint = content.indexOf(" ", midPoint);
                if (insertPoint == -1) {
                    insertPoint = midPoint;
                }

                return "<p>" + content.substring(0, insertPoint) +
                        " " + name + " " +
                        content.substring(insertPoint) + "</p>";
            case RANDOM:
                // 随机选择一个位置（除了RANDOM和ALL）
                ContentPosition[] positions = {
                        ContentPosition.START,
                        ContentPosition.MIDDLE,
                        ContentPosition.END
                };
                return processContent(name, content,
                        positions[new Random().nextInt(positions.length)]);
            default:
                return content;
        }
    }
}